/*
 * Classe necessaria per gestire in maniera semplice
 * e ordinata gli intorno 5x5.
 * /

/**
 *
 * @author dario
*/

package core;
import java.awt.*;
import java.awt.image.*;

public class Neighborhood 
{
    //Coordinate del centro dell'intorno
    private int _x = 0;
    private int _y = 0;
    private int _width = 0;
    
    
    
    public Neighborhood(int width, int x, int y)
    {
        _x = x;
        _y = y;
        _width = width;
    }
    
    
    
    public void setPosition(int x, int y)
    {
        _x = x;
        _y = y;
    }
    
    public int getCenterX()
    {
        return _x;
    }
    
    public int getCenterY()
    {
        return _y;
    }
    
   
    
    /*
     * Imposta il valore dell'intorno partendo dall'immagine a toni di grigio corrispondente 
     */
    
    
    
    public Neighborhood clone()
    {
        Neighborhood clone = new Neighborhood(_width, _x, _y);
        
        return clone;
    }
    
    public int getWidth()
    {
        return _width;
    }
    
    public int[][] getRedValuesFromImage(BufferedImage img)
    {
       int[][] redvalues = new int[_width][_width];
       for(int i=0; i<_width; i++)
           for(int j=0; j<_width; j++)
           {

                    redvalues[i][j] = new Color(img.getRGB(_y-_width/2+i, _x-_width/2+j)).getRed();
           }
       return redvalues;
    }
    
    public int[][] getGreenValuesFromImage(BufferedImage img)
    {
       int[][] greenvalues = new int[_width][_width];
       for(int i=0; i<_width; i++)
           for(int j=0; j<_width; j++)
           {
               greenvalues[i][j] = new Color(img.getRGB(_y-_width/2+i, _x-_width/2+j)).getGreen();
           }
       return greenvalues;
    }
        
    public int[][] getBlueValuesFromImage(BufferedImage img)
    {
       int[][] bluevalues = new int[_width][_width];
       for(int i=0; i<_width; i++)
           for(int j=0; j<_width; j++)
           {
               bluevalues[i][j] = new Color(img.getRGB(_y-_width/2+i, _x-_width/2+j)).getBlue();
           }
       return bluevalues;
    }
    
    public int[][] getLuminanceFromImage(BufferedImage img)
    {
       int[][] values = new int[_width][_width];
       for(int i=0; i<_width; i++)
           for(int j=0; j<_width; j++)
           {
                /*if (_x-_width/2+i >= img.getWidth() || _y-_width/2+j >= img.getHeight())
                    values[i][j] = 255;
                else*/
                    values[i][j] = (new Color(img.getRGB(_y-_width/2+i, _x-_width/2+j)).getRed() + new Color(img.getRGB(_y-_width/2+i, _x-_width/2+j)).getBlue() + new Color(img.getRGB(_y-_width/2+i, _x-_width/2+j)).getGreen())/3;
           }
       return values;
    }


    public static double distance(Neighborhood query, Neighborhood target, BufferedImage img)
    {
    	double value = 0.0;
        int[][] values1 = query.getLuminanceFromImage(img);
        int[][] values2 = target.getLuminanceFromImage(img);
        for (int i=0; i<query.getWidth(); i++)
            for(int j=0; j<query.getWidth(); j++)
            {
                //Al momento lo calcolo soltanto su un canale
                value = value + (Math.pow((float)values1[i][j]/256 - (float)values2[i][j]/256, 2));
            }
        return Math.sqrt(value);
    	
    }
    
    public static double distance2(Neighborhood query, Neighborhood target, BufferedImage output_image, BufferedImage img)
    {
    	double value = 0.0;
        int[][] values1 = query.getLuminanceFromImage(output_image);
        int[][] values2 = target.getLuminanceFromImage(img);
        for (int i=0; i<query.getWidth(); i++)
            for(int j=0; j<query.getWidth(); j++)
            {
                //Al momento lo calcolo soltanto su un canale
                value = value + (Math.pow((float)values1[i][j]/256 - (float)values2[i][j]/256, 2));
            }
        return Math.sqrt(value);
    	
    }
    
    public int getOriginX()
    {
        return _x-_width/2;
    }
    
    public int getOriginY()
    {
        return _y-_width/2;
    }
}
